// ------------------------------------------------------------------------------------------
// Licensed by Interprise Solutions.
// http://www.InterpriseSolutions.com
// For details on this license please visit  the product homepage at the URL above.
// THE ABOVE NOTICE MUST REMAIN INTACT.
// ------------------------------------------------------------------------------------------
using System;
using System.Collections.Generic;
using System.Text;
using System.IO;
using System.Web;
using System.Web.Security;
using System.Security;
using System.Security.Principal;
using System.Web.UI;

namespace InterpriseSuiteEcommerceCommon.InterpriseIntegration.Authentication
{
    public class RestrictedResourceAuthenticationModule : IHttpModule
    {
        public RestrictedResourceAuthenticationModule() { }

        #region IHttpModule Members

        public void Dispose()
        {
        }

        public void Init(HttpApplication context)
        {
            context.BeginRequest += new EventHandler(HandleBeginRequest);
            context.AuthenticateRequest += new EventHandler(HandleAuthenticateRequest);
        }

        private void HandleBeginRequest(object sender, EventArgs e)
        {
            HttpApplication app = sender as HttpApplication;
            if(null != app)
            {
                RestrictedResourceInfo info;
                if (RestrictedResourceManager.IsEnabled() && 
                    RestrictedResourceManager.IsRestricted(app.Request.PhysicalPath, out info))
                {
                    HttpCookie authCookie = app.Request.Cookies[info.Name];
                    if(null == authCookie)
                    {
                        return;
                    }

                    FormsAuthenticationTicket ticket = null;
                    try
                    {
                        ticket = FormsAuthentication.Decrypt(authCookie.Value);
                    }
                    catch
                    {
                        // failed to decrypt
                        return;
                    }

                    if (null == ticket)
                    {
                        // could not decrypt
                        return;
                    }

                    FormsIdentity identity = new FormsIdentity(ticket);
                    IPrincipal associatedPrincipal = PrincipalFactory.CreatePrincipal(info.AssociatedPrincipalType, identity);

                    if (null == associatedPrincipal)
                    {
                        // could not load principal
                        return;
                    }

                    // principal found
                    app.Context.User = associatedPrincipal;                    
                }
            }
        }

        private void HandleAuthenticateRequest(object sender, EventArgs e)
        {
            HttpApplication app = sender as HttpApplication;
            if (null != app)
            {
                RestrictedResourceInfo info;

                if (RestrictedResourceManager.IsEnabled() && 
                    RestrictedResourceManager.IsRestricted(app.Request.PhysicalPath, out info))
                {
                    if (null == app.User || 
                        !app.User.GetType().Equals(info.AssociatedPrincipalType))
                    {
                        //  at this point we should have verified that the
                        //  login url is valid
                        string loginPath = app.Server.MapPath(info.LoginUrl);

                        // check if we are redirecting to the login page
                        if (!loginPath.Equals(app.Request.PhysicalPath, StringComparison.InvariantCultureIgnoreCase))
                        {
                            // add the return url
                            string returnUrl = CommonLogic.ReturnURLEncode(CommonLogic.GetThisPageUrlWithQueryString());
                            app.Response.Redirect(info.LoginUrl + "?returnurl=" + returnUrl);
                        }
                    }
                }
            }
        }

        #endregion
    }
}
